package task

import (
	"encoding/json"
	"fmt"
	"strconv"
	"time"

	"webcppcluster/action"
	"webcppcluster/cache"
	"webcppcluster/config"
	"webcppcluster/lobby"
)

// InitTaskCfg 初始化任务配置
func InitTaskCfg(userid int64, datestr string, store *cache.RedisStore) {
	strKey := fmt.Sprintf(config.KeyTask, userid, datestr)
	taskinfo := make(map[string]interface{})

	for _, id := range config.TaskList {
		cfg, ok := config.TaskCfg[id]
		if !ok {
			continue
		}
		taskinfo[fmt.Sprintf("count_%d", id)] = 0
		taskinfo[fmt.Sprintf("total_%d", id)] = cfg.Total
		taskinfo[fmt.Sprintf("state_%d", id)] = config.StateNotFinish
		
		rewardJSON, _ := json.Marshal(cfg.RewardList)
		taskinfo[fmt.Sprintf("reward_%d", id)] = string(rewardJSON)
	}

	store.SetHash(strKey, taskinfo)
	store.Expire(strKey, 7*24*60*60*time.Second)
}

// GetTaskDatestr 获取任务日期字符串
func GetTaskDatestr(taskType int, today time.Time) string {
	datestr := today.Format("2006_01_02")
	switch taskType {
	case config.TypeWeek:
		datestr = lobby.GetMonday(today)
	case config.TypeMonth:
		datestr = time.Date(today.Year(), today.Month(), 1, 0, 0, 0, 0, today.Location()).Format("2006_01_02")
	case config.TypeYear:
		datestr = time.Date(today.Year(), 1, 1, 0, 0, 0, 0, today.Location()).Format("2006_01_02")
	}
	return datestr
}

// GetTaskCfg 获取任务配置
func GetTaskCfg(userid int64, version int, store *cache.RedisStore) []map[string]interface{} {
	tasklist := []map[string]interface{}{}
	now := time.Now()
	datestr := now.Format("2006_01_02")
	strKey := fmt.Sprintf(config.KeyTask, userid, datestr)

	if !store.Exists(strKey) {
		InitTaskCfg(userid, datestr, store)
	}

	for _, id := range config.TaskList {
		cfg, ok := config.TaskCfg[id]
		if !ok {
			continue
		}
		if version < cfg.Version {
			continue
		}

		taskdict := map[string]interface{}{
			"tid":        cfg.TID,
			"type":       cfg.Type,
			"iconid":     cfg.IconID,
			"series":     cfg.Series,
			"name":       cfg.Name,
			"desc":       cfg.Desc,
			"total":      cfg.Total,
			"version":    cfg.Version,
			"rewardlist": cfg.RewardList,
			"count":      0,
			"state":      config.StateInvalid,
		}

		// 获取存放该任务缓存信息的日期
		datestr = GetTaskDatestr(cfg.Type, now)
		strKey = fmt.Sprintf(config.KeyTask, userid, datestr)

		if !store.Exists(strKey) {
			tasklist = append(tasklist, taskdict)
			continue
		}

		countfield := fmt.Sprintf("count_%d", id)
		statefield := fmt.Sprintf("state_%d", id)
		rewardfield := fmt.Sprintf("reward_%d", id)

		countStr, _ := store.GetHashField(strKey, countfield)
		stateStr, _ := store.GetHashField(strKey, statefield)
		rewardStr, _ := store.GetHashField(strKey, rewardfield)

		if countStr != "" {
			taskdict["count"], _ = strconv.Atoi(countStr)
		}
		if stateStr != "" {
			taskdict["state"], _ = strconv.Atoi(stateStr)
		}
		if rewardStr != "" {
			var rewardList []config.Reward
			json.Unmarshal([]byte(rewardStr), &rewardList)
			taskdict["rewardlist"] = rewardList
		}

		tasklist = append(tasklist, taskdict)
	}

	return tasklist
}

// UserSign 用户签到
func UserSign(userid int64, signtype int, dateStr string, store *cache.RedisStore) error {
	var date time.Time
	var err error

	// 判断签到类型
	if signtype == config.SignTypeToday {
		date = time.Now()
	} else {
		date, err = time.Parse("2006-01-02", dateStr)
		if err != nil {
			return err
		}
	}

	// 根据日期设置签到key
	day := date.Day()
	monthFirst := time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, date.Location())
	dateStrFormatted := date.Format("2006_01_02")
	monthFirstStr := monthFirst.Format("2006_01_02")
	strKey := fmt.Sprintf(config.KeySign, userid, monthFirstStr)

	// 签到：使用位图存储签到数据
	store.SetBit(strKey, int64(day), 1)

	// 发送签到事件（这里需要使用protobuf）
	signData := map[string]interface{}{
		"userid":   userid,
		"signtype": signtype,
		"date":     dateStrFormatted,
	}
	
	data, _ := json.Marshal(signData)
	action.SendAction(userid, config.MSGIDSign, config.ActionSign, data, store)

	return nil
}

